\subsection{Monocromatizar}
\subsubsection{Monocromatizar \protect{$\epsilon = 1$} }
El objetivo de la funcion monocromatizar es convertir una imagen color a escala de grises. En la implementaci'on en 
\C\ la imagen se recorre linealmente como una matriz, p'ixel a p'ixel, accediendo a los valores de cada componente de color para realizar el siguiente c'alculo: \textbf{(R+2*G+B)/4}, siendo el resultado lo que se almacena en la imagen destino.

La idea en \ass es similar solo que, aprovechando la capacidad de almacenamiento de los registros de 128 bits
y teniendo en cuenta que en cada uno de estos registros entran 16 bytes, podemos procesar de hasta 5 p'ixeles
por cada lectura de memoria, en lugar de avanzar de a uno. En importante destacar que, como dijimos en la secci'on \ref{sec:ciclos-color}, inicialmente cuando leemos en memoria la imagen fuente, tambi'en cargamos un tercio del sexto p'ixel sin embargo esta informaci'on se descarta.

Lo primero que hacemos, es triplicar lo leido en memoria y aplicar desplazamientos a derecha con el fin de queden alineados los registros para una posterior suma. La figura \ref{est:m-dos} muestra como quedan los registros despu'es de dichos desplazamientos. En este momento, por ejemplo, en el byte menos significativo de cada registro tenemos el valor de color del primero p'ixel. Los valores del siguiente p'ixel se encuentran en la cuarta posici'on, y asi sucesivamente se pueden identificar cuales son los bytes que contienen los valores alineados.

\begin{figure}[h!]
\xmmW{carga}{B_5R_4 & G_4\textbf{B_4} & R_3G_3 & \textbf{B_3}R_2 & G_2\textbf{B_2} & R_1G_1 & \textbf{B_1}R_0 & G_0\textbf{B_0}}
\xmmW{desplazamiento_1}{ 00B_5&R_4\textbf{G_4} & B_4R_3 & \textbf{G_3}B_3 & R_2\textbf{G_2} & B_2R_1 & \textbf{G_1}B_1 & R_0\textbf{G_0}}
\xmmW{desplazamiento_2}{ 0000 & B_5\textbf{R_4} & G_4B_4 & \textbf{R_3}G_3 & B_3\textbf{R_2} & G_2B_2 & \textbf{R_1}G_1 & B_1\textbf{R_0}}
%\xmmD{texto}{0G_2 0B_2 & R_1G_1 & B_1R_0 & G_0B_0}
\caption{como se corren los datos de manera favorable}
\label{est:m-dos}
\end{figure}

Es claro de observar que no es posible hacer el c'alculo anteriormente descripto sin antes desempaquetar los datos, ya que de lo contrario se perderia podria saturar alguna suma. No obstante, tambi'en es claro que el resultado deberia poder ser expresado en byte. Es importante destacar que no utilizamos punto flotante ya que nuestra estrategia fue primero realizar las sumas y las multiplicaciones y por ultimo aplicar la divisi'on. Es por esto que podemos trabajar con enteros sin perder precisi'on.

Por cada uno de los registros mencionados anteriormente, desempaquetamos a words tomando como segundo operando un registro de 128
bits con ceros, y los dividimos en partes bajas y altas, como muestra la figura \ref{est:m-tres}. Luego multiplicamos el segundo registro (el que contiene los valores correspondientes al verde), luego sumamos todas las partes altas entre si y las partes bajas entre si, y por 'ultimo dividimos los resultados por cuatro. 

\begin{figure}[h!]
\xmmW{parte baja}{ 0G_2  & 0\textbf{B_2} & 0R_1 & 0G_1 & 0\textbf{B_1} & 0R_0 & 0G_0 & 0\textbf{B_0}}
\xmmW{parte alta}{ 0B_5  & 0R_4 & 0G_4 & 0\textbf{B_4} & 0R_3 & 0G_3 & 0\textbf{B_3} & 0R_2}
\caption{desempaquetado del registro base}
\label{est:m-tres}
\end{figure}

Para multiplicar y dividir usamos las instrucciones \textit{psrlw} y \textit{psllw} para realizar un desplazamiento de bits a derecha e izquierda respectivamente en cada word del registro, pues el multiplicando y el divisor son potencias de dos. 

Una vez realizados los c'alculos necesarios notemos que tenemos los resultados en dos registros separados con lo cual debemos proceder a unirlos para luego copiarlos. 

El proceso para unirlos consiste en dos partes, una es aplicar una m'ascara para generar ceros en las posiciones que tengo basura en los dos registros, y luego  combinarlos realizando un \textit{pand}. De esta manera me quedan los datos necesarios separados por ceros (figura\ref{est:m-cuatro}).

\begin{figure}[h!]
\xmmW{datos1}{ 00 & c_2 & 00 & 00 & c_1 & 00 & 00 & c_0}
\xmmW{datos2}{ 00 & 00 & 00 & c_4 & 00 & 00 & c_3 & 00}
\xmmW{datos combinados}{ 00 & c_2 & 00 & c_4 & c_1 & 00 & c_3 & c_0}
\caption{filtrado y combinaci'on usando m'ascaras \sc{\scriptsize 00FF0000FF0000FF} y \sc{\scriptsize FF0000FF0000FF00}}
\label{est:m-cuatro}
\end{figure}

Una vez que los resultados quedaron combinados en un 'unico registro utilizamos instrucciones que provee la arquitectura para intercambiar datos dentro de un registro (similar a lo realizado en \textbf{separar canales}) con el fin de colocarlos de manera contigua y luego empaquetar. Si bien 
estas instrucciones pueden afectar la performance son realmente  'utiles e indispensables para obtener la funcionalidad deseada. Una vez empaquetado nuevamente a bytes, copiamos el \textit{double word} menos significativo a memoria y con eso cubrimos los primeros 4 p'ixeles procesados.
Luego hacemos un corrimiento del registro a fin que el 'ultimo dato procesado quede en la posci'on menos significativa. Aqui nuevamente nos vemos obligados a usar un registro de prop'osito general para copiar el 'ultimo byte a memoria.

\subsubsection{Monocromatizar \protect{$\epsilon = \infty $} }
Esta funcion es bastante similar a la anterior. La implementaci'on en \C\ es identica a la anterior solo que esta vez en lugar de combinar los valores de color, debemos quedarnos con el m'aximo.

El procedimiento para la implentaci'on en \ass\ es similar cuando  $\epsilon= 1$, al menos la primera parte cuando triplicamos los registros y los desplazamos adecuadamente para alinear los valores de color. Es interesante notar que contamos con una ventaja con respecto al caso anterior ya que no necesitamos desempaquetar pues el set de instrucciones cuenta con una funcion (\textit{pmaxub}) que calcula en m'aximo byte a byte entre dos registros SSE. Esto no solo facilita el desarrollo sino que adem'as incrementa la performance con respecto al otro monocromatizar, ya que nos ahorramos la conversi'on de empaquetados. El resultado despues de calcular el m'aximo entre las tres copias del registro puede observarse en la figura \ref{est:m-seis}.

\begin{figure}[h!]
\xmmW{pmaxub}{xxxx & xxm_4 & xx & m_3xx & xxm_2 & xx & m_1xx & xxm_0}
\caption{registro una vez calculado los valores m'aximos para cada p'ixel}
\label{est:m-seis}
\end{figure}

Una vez obtenidos los m'aximos de cada p'ixel(solo nos interesan 5 de ellos), debemos reubicarlos para que queden de manera contigua. Para esto utilizamos la misma estrategia que en separar canales. Duplicamos el registro y realizamos un corrimiento de un byte a izquierda en cada \textit{word} para obtener ceros a la izquierda de cada una de las partes bajas de cada \textit{word}. En la otra copia hacemos un corrimiento a derecha y luego a izquierda separando esta vez los valores que fueron perdidos en la operaci'on del otro registro (figura \ref{est:m-siete}). 


\begin{figure}[h!]
\xmmW{corrimiento byte a izq}{xx00& m_400 & xx00 & xx00 & m_200 & xx00 & xx00 & m_000 }
\xmmW{corrimiento byte a der}{m_500 & xx00 & xx00 & m_300 & xx00 & xx00 & m_100 & xx00 }
\caption{corrimientos para generar ceros}
\label{est:m-siete}
\end{figure}

Una vez logrado esto debemos combinar los resultados en un 'unico registro, para ello utilizamos m'ascaras como lo hicimos en $\epsilon= 1$ para colocar ceros, y luego realizamos un \textit{por} para unirlos, como muestra la figura \ref{est:m-ocho}.

\begin{figure}[h!]
\xmmW{datos1}{0000& m_400 & 0000 & 0000 & m_200 & 0000 & 0000 & m_000 }
\xmmW{datos2}{m_500 & 0000 & 0000 & m_300 & 0000 & 0000 & m_100 & 0000 }
\xmmW{datos combinados}{m5_00& m_400 & 0000 & m_300 & m_200 &0000 & m_100 & m_000 }
\caption{filtrado y combinaci'on usando m'ascaras \sc{\scriptsize 00FF0000FF0000FF} y \sc{\scriptsize FF0000FF0000FF00}}
\label{est:m-ocho}
\end{figure}

Nuevamente ordenamos los contenidos de los registros utilizando las instrucciones de intercambio de words y double words, empaquetamos y de forma an'aloga a otro monocromatizar, realizamos el proceso de copiado a la imagen destino. 


 
 

